package com.mec.fileTransfer.core;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.ThreadPoolExecutor;

import com.mec.about_file.util.ByteAndString;
import com.mec.fileTransfer.view.IResourceReceiveProgress;

/**
 * 服务器端派发的与发送客户端的接收资源线程
 * 功能：与指定的发送客户端进行通信，完成资源的接收工作。
 * @author Lconf
 *
 */
public class ResourceReceiver implements Runnable {
	/**
	 * 对端socket、dis、文件接收服务器、线程池对象、进度条对象
	 */
	private Socket sender;
	private DataInputStream dis;
	private ThreadPoolExecutor threadPool;
	private ResourceReceiverServer server;
	private IResourceReceiveProgress receiveProgress;
	private Object lock;
	
	static final ThreadLocal<Integer> threadFileId 
	= new ThreadLocal<Integer>() {
		@Override
		protected Integer initialValue() {
			return -1;
		}
};
	
	
	public ResourceReceiver() {
	}
	
	protected ResourceReceiver(Socket sender, ThreadPoolExecutor threadPool, ResourceReceiverServer server,
			IResourceReceiveProgress receiveProgress) throws IOException {
		this.sender = sender;
		this.threadPool = threadPool;
		this.server = server;
		this.receiveProgress = receiveProgress;
		
		dis = new DataInputStream(sender.getInputStream());
		lock = new Object();
		
		synchronized (lock) {
			threadPool.execute(this);
			try {
				lock.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	void closeReciever() {
		try {
			if (dis != null) {
				dis.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			dis = null;
		}
		try {
			if (sender != null && !sender.isClosed()) {
				sender.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			sender = null;
		}
	}

	/**
	 * 按流程接收客户端发来的信息。
	 * 1、16字节表示header
	 * 2、接收16字节说明的后续内容，如果header标志位为结束
	 * 	则结束接收工作。
	 * 
	 */
	@Override
	public void run() {
		boolean finished = false;
		
		synchronized (lock) {
			lock.notify();
		}
		
		while(!finished) {
			try {
				finished = receiveBlock();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				finished = true;
				e.printStackTrace();
			} 
		}
		closeReciever();
		
	}
	
	//接收固定字节长度的字节内容到Byte[]数组中，并将对象返回
	private byte[] receiveBytes(int length) throws IOException {
		byte[] buffer = new byte[length];
		int curentOffset = 0;
		while(length > 0) {
			int readReadCount = dis.read(buffer, curentOffset, length);
			curentOffset += readReadCount;
			length -= readReadCount;
		}
		
		return buffer;
	}
	
	//安排接收客户端发送的流程
	private boolean receiveBlock() throws IOException {
		byte[] header = receiveBytes(16);
		int fileId = ByteAndString.getIntAt(header, 0);
		long offset = ByteAndString.getLongAt(header, 4);
		int length = ByteAndString.getIntAt(header, 12);
		byte[] context = new byte[length];
		int offsetInArr = 0;
		
		if(fileId == -1) {
			return true;
		}
		//进度条待处理
		if (receiveProgress != null) {
			int oldFileId = threadFileId.get();
			//如果这个文件的进度条不存在，则根据id在set中找到这个文件信息，并增加一个新的进度条。
			if (oldFileId != fileId) {
				threadFileId.set(fileId);
				ReceiveFileModel rfm = server
						.getReseiveFileSet()
						.getReceiveFile(fileId);
				//System.out.println("exception at FILEID is [" + fileId + "]");
				String fileName = rfm.getFilePath();
				int fileLength = (int) rfm.getLength();
				//进度条中增加一个新的进度，表示
				receiveProgress.receiveNewFile(fileId, fileName, fileLength);
			}
		}
		
		
		ReceiveFileSet receiveFileSet = server.getReseiveFileSet();
		ReceiveFileModel receiveFileModel = receiveFileSet.getReceiveFile(fileId);
		
		int ctlLengthVar = length;
		//System.out.println("ctlLengthVar: [" + ctlLengthVar);
		while(ctlLengthVar > 0) {
			int realReadLen = dis.read(context, offsetInArr, ctlLengthVar);
			offsetInArr += realReadLen;
			ctlLengthVar -= realReadLen;
		}
		
		new ResourceBlock
		(offset, length, context, receiveFileModel, threadPool, receiveProgress)
			.setFileId(fileId).startWirte();
		
		return false;
	}
	
	
	
}
